/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/14/2022)
 *         Author:  Zhang Changxing <ZhangChangxingVIP@163.com>
 *      ChangeLog:  1, Release initial version on "04/14/2022 08:36:03 PM"
 *                 
 ********************************************************************************/

#include "main.h"

#define MAX_EVENTS 512
#define	DB_NAME	"temperature"

static inline  void print_usage(char *programe);

int main (int argc, char **argv)
{
	struct epoll_event 	event;
	struct epoll_event 	event_array[MAX_EVENTS];
	int					listenfd;
	char				buf[1024];
	int					ch;
	int					port = 0;
	int					epollfd = -1;
	int					events = -1;
	int					daemon_run = 0;
	int 				i;
	int					rev;
	int 				connfd = -1;
	pack_info_t 		pack_info;

    if( logger_init("../logger/running.log", LOG_LEVEL_INFO) < 0)
    {
        fprintf(stderr, "initial logger system failure\n");
        return 1;
    }

	log_error("\n\n\n");
	log_error("*************************************************************************");
	log_error("*                     The server starts running                         *");
	log_error("*************************************************************************\n");

	struct option opts[] = {
		{"port", required_argument, NULL, 'p'},
		{"help", no_argument, NULL, 'b'},
		{0, 0, 0, 0}
	};
	
	while ((ch = getopt_long(argc, argv, "p:h", opts, NULL)) != -1)
	{
		switch (ch)
		{
			case 'b':
				{
					daemon_run = 1;
					break;
				}
			case 'p':
				{
					port = atoi(optarg);
					break;
				}
			case 'h':
				{
					print_usage(argv[0]);
					break;
				}
			default:
				{
					log_error("Invalid argument!\n");
					return -1;
				}
		}
	}

	if (!port)
	{ 
		log_error("The port is NULL!\n");
		return -2;
	}

	if (daemon_run)
	{
		if (daemon(0, 0) < 0)
		{
			printf("Runing daemon failure:%s\n", strerror(errno));
			return -3;
		}
		log_debug("Runing daemon successfully!\n");
	}

	set_socket_rimit();
	listenfd = socket_init(NULL, port);

	epollfd = epoll_create(MAX_EVENTS);
	if (epollfd < 0 )
	{
		log_error("Create epoll failure:%s\n", strerror(errno));
		return -4;
	}

	event.events = EPOLLIN;
	event.data.fd = listenfd;

	if ((epoll_ctl(epollfd, EPOLL_CTL_ADD,listenfd, &event)) < 0)
	{
		log_error("Execute epoll_ctl failure:%s\n", strerror(errno));
		return -5;
	}

	if(sqlite_init(DB_NAME))
	{
		return -6;
	}

	while (1)
	{
		events = epoll_wait(epollfd, event_array, MAX_EVENTS, -1);
		for (i = 0; i < events--; i++)
		{
			if (event_array[i].events == EPOLLERR || event_array[i].events == EPOLLHUP)
			{
				log_error("Epoll wait eorr or hup!\n");
				epoll_ctl(epollfd, EPOLL_CTL_DEL, event_array[i].data.fd,NULL);
				close(event_array[i].data.fd);
			}

			if (event_array[i].data.fd == listenfd)
			{
				connfd = accept(listenfd, NULL, NULL);
				if (connfd < 0)
				{
					log_error("Server connect new client failure:%s\n", strerror(errno));
					close(connfd);
					continue;
				}

				log_debug("Server connect new client[%d] successfully!\n", connfd);

				event.events = EPOLLIN;
				event.data.fd = connfd;

				if ((epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &event)) < 0)
				{
					log_error("Add connfd to epollfd list failure:%s\n", strerror(errno));
					close(event_array[i].data.fd);
					continue;
				}
			}
			else
			{
				memset(buf, 0, sizeof(buf));

				rev =  read(connfd, buf, 35);
				if (rev < 0)
				{
					log_error("Read data from client[%d] failure:%s\n", connfd, strerror(errno));
					if (epoll_ctl(epollfd, EPOLL_CTL_DEL, event_array[i].data.fd, NULL) < 0 )
					{
						log_error("Delete connfd to epollfd list failure:%s\n", strerror(errno));
					}
					
					close(event_array[i].data.fd);
					continue;
				}
				else if (rev == 0)
				{
					log_error("Client[%d] disconnect!\n", event_array[i].data.fd);
					close(connfd);
					continue;
				}

				data_segmentation(buf, &pack_info);

				if (sqlite_create_table(pack_info.devid) == 0)
				{
					data_insert(pack_info, pack_info.devid);
				}
			}

		}
	}
	close_database();
	return 0;
} 

/* Print help information */
static inline  void print_usage(char *programe)
{
	printf("Usage:%s[OPTION]....\n", programe);
	printf("-p[port]:Socket sever port address\n");
	printf("-b[daemon]:Runing programe in background!\n");
	printf("-h[help]:Display this help information\n");
	printf("\nExample:%s -b -p 6667\n", programe);
	return;
}



